package sg.com.techstudio.tafep.dao;

import java.util.LinkedList;
import java.util.List;

import org.apache.commons.lang3.math.NumberUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import sg.com.techstudio.tafep.obj.ConfigObj;
import sg.com.techstudio.tafep.obj.ParticipantObj;

@Repository("configDao")
@Transactional
public class ConfigDao {
	private static final Log log = LogFactory.getLog(ConfigDao.class);
	public static final String CONFIG_TYPE_SNEF_ID = "SNEF_ID";
	public static final int TOTAL_EVENT = 7;

	@Autowired
	private SessionFactory sessionFactory;

	@SuppressWarnings("unchecked")
	public List<ConfigObj> getConfigList(String configType){
		log.debug("getConfigList() entry");
		Criteria c = sessionFactory.getCurrentSession().createCriteria(ConfigObj.class);
		c.add(Restrictions.eq("type", configType));
		c.add(Restrictions.eq("status", 1));
		return c.list();
	}

	public long[] getCapacity() {
		log.debug("getCapacity() entry");
		List<ConfigObj> configList = getConfigList("CAPACITY");
		if(configList==null)
			return null;
		long[] capacity = new long[configList.size()];
		int i=0;
		for(ConfigObj c: configList)
			capacity[i++] = NumberUtils.toLong(c.getValue());
		return capacity;
	}
	
	public long[] getRegistrantCount() {
		log.debug("getCapacity() entry");
		long[] res = new long[TOTAL_EVENT];
		int i=0;
		Criteria c = sessionFactory.getCurrentSession().createCriteria(ParticipantObj.class);
		c.add(Restrictions.eq("main", true));
		c.add(Restrictions.le("status", 1));
		c.setProjection(Projections.rowCount());
		res[i++] = (Long)c.uniqueResult();
		
		c = sessionFactory.getCurrentSession().createCriteria(ParticipantObj.class);
		c.add(Restrictions.eq("breakout1", 1));
		c.add(Restrictions.le("status", 1));
		c.setProjection(Projections.rowCount());
		res[i++] = (Long)c.uniqueResult();
		
		c = sessionFactory.getCurrentSession().createCriteria(ParticipantObj.class);
		c.add(Restrictions.eq("breakout1", 2));
		c.add(Restrictions.le("status", 1));
		c.setProjection(Projections.rowCount());
		res[i++] = (Long)c.uniqueResult();
		
		c = sessionFactory.getCurrentSession().createCriteria(ParticipantObj.class);
		c.add(Restrictions.eq("breakout2", 1));
		c.add(Restrictions.le("status", 1));
		c.setProjection(Projections.rowCount());
		res[i++] = (Long)c.uniqueResult();
		
		c = sessionFactory.getCurrentSession().createCriteria(ParticipantObj.class);
		c.add(Restrictions.eq("breakout2", 2));
		c.add(Restrictions.le("status", 1));
		c.setProjection(Projections.rowCount());
		res[i++] = (Long)c.uniqueResult();
		
		c = sessionFactory.getCurrentSession().createCriteria(ParticipantObj.class);
		c.add(Restrictions.eq("post1", true));
		c.add(Restrictions.le("status", 1));
		c.setProjection(Projections.rowCount());
		res[i++] = (Long)c.uniqueResult();
		
		c = sessionFactory.getCurrentSession().createCriteria(ParticipantObj.class);
		c.add(Restrictions.eq("post2", true));
		c.add(Restrictions.le("status", 1));
		c.setProjection(Projections.rowCount());
		res[i++] = (Long)c.uniqueResult();
		
		log.debug("Current registration count:");
		for(int j=0; j<res.length; j++)
			log.debug(res[j]);
		return res;
	}
	
	public List<Boolean> getFullFlag(int newReg) {
		log.debug("getFullFlag() entry");
		long[] capacity = getCapacity();
		long[] regcount = getRegistrantCount();
		List<Boolean> res = new LinkedList<Boolean>();
		for(int i=0; i<TOTAL_EVENT; i++)
			res.add(regcount[i]+newReg>capacity[i]);
		
		log.debug("getFullFlag:"+res);
		return res;
	}

	public boolean isValidSnefId(String snefId) {
		log.debug("isValidSnefId() entry");
		Criteria c = sessionFactory.getCurrentSession().createCriteria(ConfigObj.class);
		c.add(Restrictions.eq("type", CONFIG_TYPE_SNEF_ID));
		c.add(Restrictions.eq("status", 1));
		c.add(Restrictions.eq("value", snefId));
		c.setProjection(Projections.rowCount());
		return (Long) c.uniqueResult() > 0;
	}

	@SuppressWarnings("unchecked")
	public List<ConfigObj> getSnefList(String q){
		log.debug("isValidSnefId() entry");
		Criteria c = sessionFactory.getCurrentSession().createCriteria(ConfigObj.class);
		c.add(Restrictions.eq("type", CONFIG_TYPE_SNEF_ID));
		c.add(Restrictions.eq("status", 1));
		c.add(Restrictions.ilike("value", q+"%"));
		return c.list();
	}
}
